use axum::{
    extract::rejection::{FormRejection, JsonRejection},
    http::StatusCode,
    response::IntoResponse,
    Json,
};
use redis::RedisError;
use validator::ValidationErrors;

pub enum ServerError {
    Authentication,
    Validation(ValidationErrors),
    JsonDeserialize,
    FormDeserialize,
    RedisError,
}

impl IntoResponse for ServerError {
    fn into_response(self) -> axum::response::Response {
        let (status_code, error_message) = match self {
            Self::Authentication => (StatusCode::UNAUTHORIZED, "身份验证失败!".to_string()),
            Self::Validation(error) => (StatusCode::UNPROCESSABLE_ENTITY, error.to_string()),
            Self::JsonDeserialize => (StatusCode::BAD_REQUEST, "json数据反序列化失败!".to_string()),
            Self::FormDeserialize => (StatusCode::BAD_REQUEST, "表单数据反序列化失败!".to_string()),
            Self::RedisError => (StatusCode::INTERNAL_SERVER_ERROR, "redis错误!".to_string()),
        };
        let body = Json(serde_json::json!({
            "error": error_message,
        }));
        (status_code, body).into_response()
    }
}

impl From<JsonRejection> for ServerError {
    fn from(_value: JsonRejection) -> Self {
        Self::JsonDeserialize
    }
}

impl From<FormRejection> for ServerError {
    fn from(_value: FormRejection) -> Self {
        Self::FormDeserialize
    }
}

impl From<ValidationErrors> for ServerError {
    fn from(value: ValidationErrors) -> Self {
        Self::Validation(value)
    }
}

impl From<RedisError> for ServerError {
    fn from(_value: RedisError) -> Self {
        Self::RedisError
    }
}
